use super::BitWindow;

#[derive(Debug, Eq, PartialEq)]
pub enum Error {
    MissingBits(BitWindow),
    Unhandled(BitWindow, usize),
}

#[derive(Clone, Debug)]
enum DecodeValue {
    Partial(&'static HuffmanDecoder),
    Sym(u8),
}

#[derive(Clone, Debug)]
struct HuffmanDecoder {
    lookup: u32,
    table: &'static [DecodeValue],
}

impl HuffmanDecoder {
    fn check_eof(&self, bit_pos: &mut BitWindow, input: &[u8]) -> Result<Option<u32>, Error> {
        use std::cmp::Ordering;
        match ((bit_pos.byte + 1) as usize).cmp(&input.len()) {
            // Position is out-of-range
            Ordering::Greater => {
                return Ok(None);
            }
            // Position is on the last byte
            Ordering::Equal => {
                let side = bit_pos.opposite_bit_window();

                let rest = match read_bits(input, side.byte, side.bit, side.count) {
                    Ok(x) => x,
                    Err(()) => {
                        return Err(Error::MissingBits(side));
                    }
                };

                let eof_filler = ((2u16 << (side.count - 1)) - 1) as u8;
                if rest & eof_filler == eof_filler {
                    return Ok(None);
                }
            }
            Ordering::Less => {}
        }
        Err(Error::MissingBits(bit_pos.clone()))
    }

    fn fetch_value(&self, bit_pos: &mut BitWindow, input: &[u8]) -> Result<Option<u32>, Error> {
        match read_bits(input, bit_pos.byte, bit_pos.bit, bit_pos.count) {
            Ok(value) => Ok(Some(value as u32)),
            Err(()) => self.check_eof(bit_pos, input),
        }
    }

    fn decode_next(&self, bit_pos: &mut BitWindow, input: &[u8]) -> Result<Option<u8>, Error> {
        bit_pos.forwards(self.lookup);

        let value = match self.fetch_value(bit_pos, input) {
            Ok(Some(value)) => value as usize,
            Ok(None) => return Ok(None),
            Err(err) => return Err(err),
        };

        let at_value = match (self.table).get(value) {
            Some(x) => x,
            None => return Err(Error::Unhandled(bit_pos.clone(), value)),
        };

        match at_value {
            DecodeValue::Sym(x) => Ok(Some(*x)),
            DecodeValue::Partial(d) => d.decode_next(bit_pos, input),
        }
    }
}

/// Read `len` bits from the `src` slice at the specified position
///
/// Never read more than 8 bits at a time. `bit_offset` may be larger than 8.
fn read_bits(src: &[u8], mut byte_offset: u32, mut bit_offset: u32, len: u32) -> Result<u8, ()> {
    if len == 0 || len > 8 || src.len() as u32 * 8 < (byte_offset * 8) + bit_offset + len {
        return Err(());
    }

    // Deal with `bit_offset` > 8
    byte_offset += bit_offset / 8;
    bit_offset -= (bit_offset / 8) * 8;

    Ok(if bit_offset + len <= 8 {
        // Read all the bits from a single byte
        (src[byte_offset as usize] << bit_offset) >> (8 - len)
    } else {
        // The range of bits spans over 2 bytes
        let mut result = (src[byte_offset as usize] as u16) << 8;
        result |= src[byte_offset as usize + 1] as u16;
        ((result << bit_offset) >> (16 - len)) as u8
    })
}

macro_rules! bits_decode {
    // general way
    (
        lookup: $count:expr, [
        $($sym:expr,)*
        $(=> $sub:ident,)* ]
    ) => {
        HuffmanDecoder {
            lookup: $count,
            table: &[
                $( DecodeValue::Sym($sym as u8), )*
                $( DecodeValue::Partial(&$sub), )*
            ]
        }
    };
    // 2-final
    ( $first:expr, $second:expr ) => {
        HuffmanDecoder {
            lookup: 1,
            table: &[
                DecodeValue::Sym($first as u8),
                DecodeValue::Sym($second as u8),
            ]
        }
    };
    // 4-final
    ( $first:expr, $second:expr, $third:expr, $fourth:expr ) => {
        HuffmanDecoder {
            lookup: 2,
            table: &[
                DecodeValue::Sym($first as u8),
                DecodeValue::Sym($second as u8),
                DecodeValue::Sym($third as u8),
                DecodeValue::Sym($fourth as u8),
            ]
        }
    };
    // 2-final-partial
    ( $first:expr, => $second:ident ) => {
        HuffmanDecoder {
            lookup: 1,
            table: &[
                DecodeValue::Sym($first as u8),
                DecodeValue::Partial(&$second),
            ]
        }
    };
    // 2-partial
    ( => $first:ident, => $second:ident ) => {
        HuffmanDecoder {
            lookup: 1,
            table: &[
                DecodeValue::Partial(&$first),
                DecodeValue::Partial(&$second),
            ]
        }
    };
    // 4-partial
    ( => $first:ident, => $second:ident,
      => $third:ident, => $fourth:ident ) => {
        HuffmanDecoder {
            lookup: 2,
            table: &[
                DecodeValue::Partial(&$first),
                DecodeValue::Partial(&$second),
                DecodeValue::Partial(&$third),
                DecodeValue::Partial(&$fourth),
            ]
        }
    };
    [ $( $name:ident => ( $($value:tt)* ), )* ] => {
        $( const $name: HuffmanDecoder = bits_decode!( $( $value )* ); )*
    };
}

#[rustfmt::skip]
bits_decode![
    HPACK_STRING => (
        lookup: 5, [ '0', '1', '2', 'a', 'c', 'e', 'i', 'o', 's', 't',
        => END0_01010, => END0_01011, => END0_01100, => END0_01101,
        => END0_01110, => END0_01111, => END0_10000, => END0_10001,
        => END0_10010, => END0_10011, => END0_10100, => END0_10101,
        => END0_10110, => END0_10111, => END0_11000, => END0_11001,
        => END0_11010, => END0_11011, => END0_11100, => END0_11101,
        => END0_11110, => END0_11111,
        ]),
    END0_01010 => ( 32, '%'),
    END0_01011 => ('-', '.'),
    END0_01100 => ('/', '3'),
    END0_01101 => ('4', '5'),
    END0_01110 => ('6', '7'),
    END0_01111 => ('8', '9'),
    END0_10000 => ('=', 'A'),
    END0_10001 => ('_', 'b'),
    END0_10010 => ('d', 'f'),
    END0_10011 => ('g', 'h'),
    END0_10100 => ('l', 'm'),
    END0_10101 => ('n', 'p'),
    END0_10110 => ('r', 'u'),
    END0_10111 => (':', 'B', 'C', 'D'),
    END0_11000 => ('E', 'F', 'G', 'H'),
    END0_11001 => ('I', 'J', 'K', 'L'),
    END0_11010 => ('M', 'N', 'O', 'P'),
    END0_11011 => ('Q', 'R', 'S', 'T'),
    END0_11100 => ('U', 'V', 'W', 'Y'),
    END0_11101 => ('j', 'k', 'q', 'v'),
    END0_11110 => ('w', 'x', 'y', 'z'),
    END0_11111 => (=> END5_00, => END5_01, => END5_10, => END5_11),
    END5_00 => ('&', '*'),
    END5_01 => (',', 59),
    END5_10 => ('X', 'Z'),
    END5_11 => (=> END7_0, => END7_1),
    END7_0 => ('!', '"', '(', ')'),
    END7_1 => (=> END8_0, => END8_1),
    END8_0 => ('?', => END9A_1),
    END9A_1 => ('\'', '+'),
    END8_1 => (lookup: 2, ['|', => END9B_01, => END9B_10, => END9B_11,]),
    END9B_01 => ('#', '>'),
    END9B_10 => (0, '$', '@', '['),
    END9B_11 => (lookup: 2, [']', '~', => END13_10, => END13_11,]),
    END13_10 => ('^', '}'),
    END13_11 => (=> END14_0, => END14_1),
    END14_0 => ('<', '`'),
    END14_1 => ('{', => END15_1),
    END15_1 =>
    (lookup: 4, [ '\\', 195, 208, => END19_0011,
     => END19_0100, => END19_0101, => END19_0110, => END19_0111,
     => END19_1000, => END19_1001, => END19_1010, => END19_1011,
     => END19_1100, => END19_1101, => END19_1110, => END19_1111,
    ]),
    END19_0011 => (128, 130),
    END19_0100 => (131, 162),
    END19_0101 => (184, 194),
    END19_0110 => (224, 226),
    END19_0111 => (153, 161, 167, 172),
    END19_1000 => (176, 177, 179, 209),
    END19_1001 => (216, 217, 227, 229),
    END19_1010 => (lookup: 2, [230, => END19_1010_01, => END19_1010_10,
                   => END19_1010_11,]),
    END19_1010_01 => (129, 132),
    END19_1010_10 => (133, 134),
    END19_1010_11 => (136, 146),
    END19_1011 => (lookup: 3, [154, 156, 160, 163, 164, 169, 170, 173,]),
    END19_1100 => (lookup: 3, [178, 181, 185, 186, 187, 189, 190, 196,]),
    END19_1101 => (lookup: 3, [198, 228, 232, 233,
                   => END23A_100, => END23A_101,
                   => END23A_110, => END23A_111,]),
    END23A_100 => (  1, 135),
    END23A_101 => (137, 138),
    END23A_110 => (139, 140),
    END23A_111 => (141, 143),
    END19_1110 => (lookup: 4, [147, 149, 150, 151, 152, 155, 157, 158,
                   165, 166, 168, 174, 175, 180, 182, 183,]),
    END19_1111 => (lookup: 4, [188, 191, 197, 231, 239,
                   => END23B_0101, => END23B_0110, => END23B_0111,
                   => END23B_1000, => END23B_1001, => END23B_1010,
                   => END23B_1011, => END23B_1100, => END23B_1101,
                   => END23B_1110, => END23B_1111,]),
    END23B_0101 => (  9, 142),
    END23B_0110 => (144, 145),
    END23B_0111 => (148, 159),
    END23B_1000 => (171, 206),
    END23B_1001 => (215, 225),
    END23B_1010 => (236, 237),
    END23B_1011 => (199, 207, 234, 235),
    END23B_1100 => (lookup: 3, [192, 193, 200, 201, 202, 205, 210, 213,]),
    END23B_1101 => (lookup: 3, [218, 219, 238, 240, 242, 243, 255,
                    => END27A_111,]),
    END27A_111 => (203, 204),
    END23B_1110 => (lookup: 4, [211, 212, 214, 221, 222, 223, 241, 244,
                    245, 246, 247, 248, 250, 251, 252, 253,]),
    END23B_1111 => (lookup: 4, [ 254, => END27B_0001, => END27B_0010,
                    => END27B_0011, => END27B_0100, => END27B_0101,
                    => END27B_0110, => END27B_0111, => END27B_1000,
                    => END27B_1001, => END27B_1010, => END27B_1011,
                    => END27B_1100, => END27B_1101, => END27B_1110,
                    => END27B_1111,]),
    END27B_0001 => (2, 3),
    END27B_0010 => (4, 5),
    END27B_0011 => (6, 7),
    END27B_0100 => (8, 11),
    END27B_0101 => (12, 14),
    END27B_0110 => (15, 16),
    END27B_0111 => (17, 18),
    END27B_1000 => (19, 20),
    END27B_1001 => (21, 23),
    END27B_1010 => (24, 25),
    END27B_1011 => (26, 27),
    END27B_1100 => (28, 29),
    END27B_1101 => (30, 31),
    END27B_1110 => (127, 220),
    END27B_1111 => (lookup: 1, [249, => END31_1,]),
    END31_1 => (lookup: 2, [10, 13, 22, => EOF,]),
    EOF => (lookup: 8, []),
    ];

pub struct DecodeIter<'a> {
    bit_pos: BitWindow,
    content: &'a Vec<u8>,
}

impl<'a> Iterator for DecodeIter<'a> {
    type Item = Result<u8, Error>;

    fn next(&mut self) -> Option<Self::Item> {
        match HPACK_STRING.decode_next(&mut self.bit_pos, self.content) {
            Ok(Some(x)) => Some(Ok(x)),
            Err(err) => Some(Err(err)),
            Ok(None) => None,
        }
    }
}

pub trait HpackStringDecode {
    fn hpack_decode(&self) -> DecodeIter;
}

impl HpackStringDecode for Vec<u8> {
    fn hpack_decode(&self) -> DecodeIter {
        DecodeIter {
            bit_pos: BitWindow::new(),
            content: self,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_read_bits() {
        // Basic case (within one byte, aligned with start)
        assert_eq!(read_bits(&[0b1010_1010], 0, 0, 5), Ok(0b1_0101));
        // Within one byte, aligned with end of byte
        assert_eq!(read_bits(&[0b1010_1010], 0, 3, 5), Ok(0b1010));
        // Within one byte, unaligned with either side
        assert_eq!(read_bits(&[0b1010_1010], 0, 3, 3), Ok(0b10));
        // `len` == 0
        assert_eq!(read_bits(&[0b1010_1010], 0, 0, 0), Err(()));
        // `len` > 8
        assert_eq!(read_bits(&[0b1010_1010], 0, 0, 9), Err(()));

        // `bit_offset` > 7
        assert_eq!(read_bits(&[0b1010_1010, 0b1010_1010], 0, 8, 8), Ok(0b1010_1010));
        // Read spanning two bytes
        assert_eq!(read_bits(&[0b1010_1010, 0b1010_1010], 0, 4, 8), Ok(0b1010_1010));
        // Read with non-zero `byte_offset`
        assert_eq!(read_bits(&[0b1010_1010, 0b1010_1010], 1, 0, 5), Ok(0b1_0101));
        // Read with `bit_offset` > 7, unaligned with either side
        assert_eq!(read_bits(&[0b1010_1010, 0b1010_1010], 0, 10, 5), Ok(0b1_0101));
        // Read with `bit_offset` > 7 past end of input slice
        assert_eq!(read_bits(&[0b1010_1010, 0b1010_1010], 0, 16, 5), Err(()));
    }

    macro_rules! decoding {
        [ $( $code:expr => $( $byte:expr ),* ; )* ] => { $( {
            let bytes = vec![$( $byte ),*];
            let res: Result<Vec<_>, Error> = bytes.hpack_decode().collect();
            assert_eq!(res, Ok(vec![$code]), "fail to decode {}", $code);
        } )* }
    }

    /**
     * https://tools.ietf.org/html/rfc7541
     * Appendix B.  Huffman Code
     */
    #[test]
    #[allow(clippy::cognitive_complexity)]
    fn test_decode_single_value() {
        decoding![
            48 => (0b0_0000 << 3) | /* padding */ 0b111; // '0'
        49 => (0b0_0001 << 3) | /* padding */ 0b111; // '1'
        50 => (0b0_0010 << 3) | /* padding */ 0b111; // '2'
        97 => (0b0_0011 << 3) | /* padding */ 0b111; // 'a'
        99 => (0b0_0100 << 3) | /* padding */ 0b111; // 'c'
        101 => (0b0_0101 << 3) | /* padding */ 0b111; // 'e'
        105 => (0b0_0110 << 3) | /* padding */ 0b111; // 'i'
        111 => (0b0_0111 << 3) | /* padding */ 0b111; // 'o'
        115 => (0b0_1000 << 3) | /* padding */ 0b111; // 's'
        116 => (0b0_1001 << 3) | /* padding */ 0b111; // 't'
        32 => (0b01_0100 << 2) | /* padding */ 0b11;
        37 => (0b01_0101 << 2) | /* padding */ 0b11; // '%'
        45 => (0b01_0110 << 2) | /* padding */ 0b11; // '-'
        46 => (0b01_0111 << 2) | /* padding */ 0b11; // '.'
        47 => (0b01_1000 << 2) | /* padding */ 0b11; // '/'
        51 => (0b01_1001 << 2) | /* padding */ 0b11; // '3'
        52 => (0b01_1010 << 2) | /* padding */ 0b11; // '4'
        53 => (0b01_1011 << 2) | /* padding */ 0b11; // '5'
        54 => (0b01_1100 << 2) | /* padding */ 0b11; // '6'
        55 => (0b01_1101 << 2) | /* padding */ 0b11; // '7'
        56 => (0b01_1110 << 2) | /* padding */ 0b11; // '8'
        57 => (0b01_1111 << 2) | /* padding */ 0b11; // '9'
        61 => (0b10_0000 << 2) | /* padding */ 0b11; // '='
        65 => (0b10_0001 << 2) | /* padding */ 0b11; // 'A'
        95 => (0b10_0010 << 2) | /* padding */ 0b11; // '_'
        98 => (0b10_0011 << 2) | /* padding */ 0b11; // 'b'
        100 => (0b10_0100 << 2) | /* padding */ 0b11; // 'd'
        102 => (0b10_0101 << 2) | /* padding */ 0b11; // 'f'
        103 => (0b10_0110 << 2) | /* padding */ 0b11; // 'g'
        104 => (0b10_0111 << 2) | /* padding */ 0b11; // 'h'
        108 => (0b10_1000 << 2) | /* padding */ 0b11; // 'l'
        109 => (0b10_1001 << 2) | /* padding */ 0b11; // 'm'
        110 => (0b10_1010 << 2) | /* padding */ 0b11; // 'n'
        112 => (0b10_1011 << 2) | /* padding */ 0b11; // 'p'
        114 => (0b10_1100 << 2) | /* padding */ 0b11; // 'r'
        117 => (0b10_1101 << 2) | /* padding */ 0b11; // 'u'
        58 => (0b101_1100 << 1) | /* padding */ 0b1; // ':'
        66 => (0b101_1101 << 1) | /* padding */ 0b1; // 'B'
        67 => (0b101_1110 << 1) | /* padding */ 0b1; // 'C'
        68 => (0b101_1111 << 1) | /* padding */ 0b1; // 'D'
        69 => (0b110_0000 << 1) | /* padding */ 0b1; // 'E'
        70 => (0b110_0001 << 1) | /* padding */ 0b1; // 'F'
        71 => (0b110_0010 << 1) | /* padding */ 0b1; // 'G'
        72 => (0b110_0011 << 1) | /* padding */ 0b1; // 'H'
        73 => (0b110_0100 << 1) | /* padding */ 0b1; // 'I'
        74 => (0b110_0101 << 1) | /* padding */ 0b1; // 'J'
        75 => (0b110_0110 << 1) | /* padding */ 0b1; // 'K'
        76 => (0b110_0111 << 1) | /* padding */ 0b1; // 'L'
        77 => (0b110_1000 << 1) | /* padding */ 0b1; // 'M'
        78 => (0b110_1001 << 1) | /* padding */ 0b1; // 'N'
        79 => (0b110_1010 << 1) | /* padding */ 0b1; // 'O'
        80 => (0b110_1011 << 1) | /* padding */ 0b1; // 'P'
        81 => (0b110_1100 << 1) | /* padding */ 0b1; // 'Q'
        82 => (0b110_1101 << 1) | /* padding */ 0b1; // 'R'
        83 => (0b110_1110 << 1) | /* padding */ 0b1; // 'S'
        84 => (0b110_1111 << 1) | /* padding */ 0b1; // 'T'
        85 => (0b111_0000 << 1) | /* padding */ 0b1; // 'U'
        86 => (0b111_0001 << 1) | /* padding */ 0b1; // 'V'
        87 => (0b111_0010 << 1) | /* padding */ 0b1; // 'W'
        89 => (0b111_0011 << 1) | /* padding */ 0b1; // 'Y'
        106 => (0b111_0100 << 1) | /* padding */ 0b1; // 'j'
        107 => (0b111_0101 << 1) | /* padding */ 0b1; // 'k'
        113 => (0b111_0110 << 1) | /* padding */ 0b1; // 'q'
        118 => (0b111_0111 << 1) | /* padding */ 0b1; // 'v'
        119 => (0b111_1000 << 1) | /* padding */ 0b1; // 'w'
        120 => (0b111_1001 << 1) | /* padding */ 0b1; // 'x'
        121 => (0b111_1010 << 1) | /* padding */ 0b1; // 'y'
        122 => (0b111_1011 << 1) | /* padding */ 0b1; // 'z'
        38 => 0b1111_1000, /* padding */ 0b1111_1111; // '&'
        42 => 0b1111_1001, /* padding */ 0b1111_1111; // '*'
        44 => 0b1111_1010, /* padding */ 0b1111_1111; // ','
        59 => 0b1111_1011, /* padding */ 0b1111_1111;
        88 => 0b1111_1100, /* padding */ 0b1111_1111; // 'X'
        90 => 0b1111_1101, /* padding */ 0b1111_1111; // 'Z'
        33 => 0b1111_1110, (0b00 << 6) | /* padding */ 0b11_1111; // '!'
        34 => 0b1111_1110, (0b01 << 6) | /* padding */ 0b11_1111; // '"'
        40 => 0b1111_1110, (0b10 << 6) | /* padding */ 0b11_1111; // '('
        41 => 0b1111_1110, (0b11 << 6) | /* padding */ 0b11_1111; // ')'
        63 => 0b1111_1111, (0b00 << 6) | /* padding */ 0b11_1111; // '?'
        39 => 0b1111_1111, (0b010 << 5) | /* padding */ 0b11111; // '''
        43 => 0b1111_1111, (0b011 << 5) | /* padding */ 0b11111; // '+'
        124 => 0b1111_1111, (0b100 << 5) | /* padding */ 0b11111; // '|'
        35 => 0b1111_1111, (0b1010 << 4) | /* padding */ 0b1111; // '#'
        62 => 0b1111_1111, (0b1011 << 4) | /* padding */ 0b1111; // '>'
        0 => 0b1111_1111, (0b11000 << 3) | /* padding */ 0b111;
        36 => 0b1111_1111, (0b11001 << 3) | /* padding */ 0b111; // '$'
        64 => 0b1111_1111, (0b11010 << 3) | /* padding */ 0b111; // '@'
        91 => 0b1111_1111, (0b11011 << 3) | /* padding */ 0b111; // '['
        93 => 0b1111_1111, (0b11100 << 3) | /* padding */ 0b111; // ']'
        126 => 0b1111_1111, (0b11101 << 3) | /* padding */ 0b111; // '~'
        94 => 0b1111_1111, (0b11_1100 << 2) | /* padding */ 0b11; // '^'
        125 => 0b1111_1111, (0b11_1101 << 2) | /* padding */ 0b11; // '}'
        60 => 0b1111_1111, (0b111_1100 << 1) | /* padding */ 0b1; // '<'
        96 => 0b1111_1111, (0b111_1101 << 1) | /* padding */ 0b1; // '`'
        123 => 0b1111_1111, (0b111_1110 << 1) | /* padding */ 0b1; // '{'
        92 => 0b1111_1111, 0b1111_1110, (0b000 << 5) | /* padding */ 0b11111; // '\'
        195 => 0b1111_1111, 0b1111_1110, (0b001 << 5) | /* padding */ 0b11111;
        208 => 0b1111_1111, 0b1111_1110, (0b010 << 5) | /* padding */ 0b11111;
        128 => 0b1111_1111, 0b1111_1110, (0b0110 << 4) | /* padding */ 0b1111;
        130 => 0b1111_1111, 0b1111_1110, (0b0111 << 4) | /* padding */ 0b1111;
        131 => 0b1111_1111, 0b1111_1110, (0b1000 << 4) | /* padding */ 0b1111;
        162 => 0b1111_1111, 0b1111_1110, (0b1001 << 4) | /* padding */ 0b1111;
        184 => 0b1111_1111, 0b1111_1110, (0b1010 << 4) | /* padding */ 0b1111;
        194 => 0b1111_1111, 0b1111_1110, (0b1011 << 4) | /* padding */ 0b1111;
        224 => 0b1111_1111, 0b1111_1110, (0b1100 << 4) | /* padding */ 0b1111;
        226 => 0b1111_1111, 0b1111_1110, (0b1101 << 4) | /* padding */ 0b1111;
        153 => 0b1111_1111, 0b1111_1110, (0b11100 << 3) | /* padding */ 0b111;
        161 => 0b1111_1111, 0b1111_1110, (0b11101 << 3) | /* padding */ 0b111;
        167 => 0b1111_1111, 0b1111_1110, (0b11110 << 3) | /* padding */ 0b111;
        172 => 0b1111_1111, 0b1111_1110, (0b11111 << 3) | /* padding */ 0b111;
        176 => 0b1111_1111, 0b1111_1111, (0b00000 << 3) | /* padding */ 0b111;
        177 => 0b1111_1111, 0b1111_1111, (0b00001 << 3) | /* padding */ 0b111;
        179 => 0b1111_1111, 0b1111_1111, (0b00010 << 3) | /* padding */ 0b111;
        209 => 0b1111_1111, 0b1111_1111, (0b00011 << 3) | /* padding */ 0b111;
        216 => 0b1111_1111, 0b1111_1111, (0b00100 << 3) | /* padding */ 0b111;
        217 => 0b1111_1111, 0b1111_1111, (0b00101 << 3) | /* padding */ 0b111;
        227 => 0b1111_1111, 0b1111_1111, (0b00110 << 3) | /* padding */ 0b111;
        229 => 0b1111_1111, 0b1111_1111, (0b00111 << 3) | /* padding */ 0b111;
        230 => 0b1111_1111, 0b1111_1111, (0b01000 << 3) | /* padding */ 0b111;
        129 => 0b1111_1111, 0b1111_1111, (0b01_0010 << 2) | /* padding */ 0b11;
        132 => 0b1111_1111, 0b1111_1111, (0b01_0011 << 2) | /* padding */ 0b11;
        133 => 0b1111_1111, 0b1111_1111, (0b01_0100 << 2) | /* padding */ 0b11;
        134 => 0b1111_1111, 0b1111_1111, (0b01_0101 << 2) | /* padding */ 0b11;
        136 => 0b1111_1111, 0b1111_1111, (0b01_0110 << 2) | /* padding */ 0b11;
        146 => 0b1111_1111, 0b1111_1111, (0b01_0111 << 2) | /* padding */ 0b11;
        154 => 0b1111_1111, 0b1111_1111, (0b01_1000 << 2) | /* padding */ 0b11;
        156 => 0b1111_1111, 0b1111_1111, (0b01_1001 << 2) | /* padding */ 0b11;
        160 => 0b1111_1111, 0b1111_1111, (0b01_1010 << 2) | /* padding */ 0b11;
        163 => 0b1111_1111, 0b1111_1111, (0b01_1011 << 2) | /* padding */ 0b11;
        164 => 0b1111_1111, 0b1111_1111, (0b01_1100 << 2) | /* padding */ 0b11;
        169 => 0b1111_1111, 0b1111_1111, (0b01_1101 << 2) | /* padding */ 0b11;
        170 => 0b1111_1111, 0b1111_1111, (0b01_1110 << 2) | /* padding */ 0b11;
        173 => 0b1111_1111, 0b1111_1111, (0b01_1111 << 2) | /* padding */ 0b11;
        178 => 0b1111_1111, 0b1111_1111, (0b10_0000 << 2) | /* padding */ 0b11;
        181 => 0b1111_1111, 0b1111_1111, (0b10_0001 << 2) | /* padding */ 0b11;
        185 => 0b1111_1111, 0b1111_1111, (0b10_0010 << 2) | /* padding */ 0b11;
        186 => 0b1111_1111, 0b1111_1111, (0b10_0011 << 2) | /* padding */ 0b11;
        187 => 0b1111_1111, 0b1111_1111, (0b10_0100 << 2) | /* padding */ 0b11;
        189 => 0b1111_1111, 0b1111_1111, (0b10_0101 << 2) | /* padding */ 0b11;
        190 => 0b1111_1111, 0b1111_1111, (0b10_0110 << 2) | /* padding */ 0b11;
        196 => 0b1111_1111, 0b1111_1111, (0b10_0111 << 2) | /* padding */ 0b11;
        198 => 0b1111_1111, 0b1111_1111, (0b10_1000 << 2) | /* padding */ 0b11;
        228 => 0b1111_1111, 0b1111_1111, (0b10_1001 << 2) | /* padding */ 0b11;
        232 => 0b1111_1111, 0b1111_1111, (0b10_1010 << 2) | /* padding */ 0b11;
        233 => 0b1111_1111, 0b1111_1111, (0b10_1011 << 2) | /* padding */ 0b11;
        1 => 0b1111_1111, 0b1111_1111, (0b101_1000 << 1) | /* padding */ 0b1;
        135 => 0b1111_1111, 0b1111_1111, (0b101_1001 << 1) | /* padding */ 0b1;
        137 => 0b1111_1111, 0b1111_1111, (0b101_1010 << 1) | /* padding */ 0b1;
        138 => 0b1111_1111, 0b1111_1111, (0b101_1011 << 1) | /* padding */ 0b1;
        139 => 0b1111_1111, 0b1111_1111, (0b101_1100 << 1) | /* padding */ 0b1;
        140 => 0b1111_1111, 0b1111_1111, (0b101_1101 << 1) | /* padding */ 0b1;
        141 => 0b1111_1111, 0b1111_1111, (0b101_1110 << 1) | /* padding */ 0b1;
        143 => 0b1111_1111, 0b1111_1111, (0b101_1111 << 1) | /* padding */ 0b1;
        147 => 0b1111_1111, 0b1111_1111, (0b110_0000 << 1) | /* padding */ 0b1;
        149 => 0b1111_1111, 0b1111_1111, (0b110_0001 << 1) | /* padding */ 0b1;
        150 => 0b1111_1111, 0b1111_1111, (0b110_0010 << 1) | /* padding */ 0b1;
        151 => 0b1111_1111, 0b1111_1111, (0b110_0011 << 1) | /* padding */ 0b1;
        152 => 0b1111_1111, 0b1111_1111, (0b110_0100 << 1) | /* padding */ 0b1;
        155 => 0b1111_1111, 0b1111_1111, (0b110_0101 << 1) | /* padding */ 0b1;
        157 => 0b1111_1111, 0b1111_1111, (0b110_0110 << 1) | /* padding */ 0b1;
        158 => 0b1111_1111, 0b1111_1111, (0b110_0111 << 1) | /* padding */ 0b1;
        165 => 0b1111_1111, 0b1111_1111, (0b110_1000 << 1) | /* padding */ 0b1;
        166 => 0b1111_1111, 0b1111_1111, (0b110_1001 << 1) | /* padding */ 0b1;
        168 => 0b1111_1111, 0b1111_1111, (0b110_1010 << 1) | /* padding */ 0b1;
        174 => 0b1111_1111, 0b1111_1111, (0b110_1011 << 1) | /* padding */ 0b1;
        175 => 0b1111_1111, 0b1111_1111, (0b110_1100 << 1) | /* padding */ 0b1;
        180 => 0b1111_1111, 0b1111_1111, (0b110_1101 << 1) | /* padding */ 0b1;
        182 => 0b1111_1111, 0b1111_1111, (0b110_1110 << 1) | /* padding */ 0b1;
        183 => 0b1111_1111, 0b1111_1111, (0b110_1111 << 1) | /* padding */ 0b1;
        188 => 0b1111_1111, 0b1111_1111, (0b111_0000 << 1) | /* padding */ 0b1;
        191 => 0b1111_1111, 0b1111_1111, (0b111_0001 << 1) | /* padding */ 0b1;
        197 => 0b1111_1111, 0b1111_1111, (0b111_0010 << 1) | /* padding */ 0b1;
        231 => 0b1111_1111, 0b1111_1111, (0b111_0011 << 1) | /* padding */ 0b1;
        239 => 0b1111_1111, 0b1111_1111, (0b111_0100 << 1) | /* padding */ 0b1;
        9 => 0b1111_1111, 0b1111_1111, 0b1110_1010, /* padding */ 0b1111_1111;
        142 => 0b1111_1111, 0b1111_1111, 0b1110_1011, /* padding */ 0b1111_1111;
        144 => 0b1111_1111, 0b1111_1111, 0b1110_1100, /* padding */ 0b1111_1111;
        145 => 0b1111_1111, 0b1111_1111, 0b1110_1101, /* padding */ 0b1111_1111;
        148 => 0b1111_1111, 0b1111_1111, 0b1110_1110, /* padding */ 0b1111_1111;
        159 => 0b1111_1111, 0b1111_1111, 0b1110_1111, /* padding */ 0b1111_1111;
        171 => 0b1111_1111, 0b1111_1111, 0b1111_0000, /* padding */ 0b1111_1111;
        206 => 0b1111_1111, 0b1111_1111, 0b1111_0001, /* padding */ 0b1111_1111;
        215 => 0b1111_1111, 0b1111_1111, 0b1111_0010, /* padding */ 0b1111_1111;
        225 => 0b1111_1111, 0b1111_1111, 0b1111_0011, /* padding */ 0b1111_1111;
        236 => 0b1111_1111, 0b1111_1111, 0b1111_0100, /* padding */ 0b1111_1111;
        237 => 0b1111_1111, 0b1111_1111, 0b1111_0101, /* padding */ 0b1111_1111;
        199 => 0b1111_1111, 0b1111_1111, 0b1111_0110, (0b0 << 7) | /* padding */ 0b111_1111;
        207 => 0b1111_1111, 0b1111_1111, 0b1111_0110, (0b1 << 7) | /* padding */ 0b111_1111;
        234 => 0b1111_1111, 0b1111_1111, 0b1111_0111, (0b0 << 7) | /* padding */ 0b111_1111;
        235 => 0b1111_1111, 0b1111_1111, 0b1111_0111, (0b1 << 7) | /* padding */ 0b111_1111;
        192 => 0b1111_1111, 0b1111_1111, 0b1111_1000, (0b00 << 6) | /* padding */ 0b11_1111;
        193 => 0b1111_1111, 0b1111_1111, 0b1111_1000, (0b01 << 6) | /* padding */ 0b11_1111;
        200 => 0b1111_1111, 0b1111_1111, 0b1111_1000, (0b10 << 6) | /* padding */ 0b11_1111;
        201 => 0b1111_1111, 0b1111_1111, 0b1111_1000, (0b11 << 6) | /* padding */ 0b11_1111;
        202 => 0b1111_1111, 0b1111_1111, 0b1111_1001, (0b00 << 6) | /* padding */ 0b11_1111;
        205 => 0b1111_1111, 0b1111_1111, 0b1111_1001, (0b01 << 6) | /* padding */ 0b11_1111;
        210 => 0b1111_1111, 0b1111_1111, 0b1111_1001, (0b10 << 6) | /* padding */ 0b11_1111;
        213 => 0b1111_1111, 0b1111_1111, 0b1111_1001, (0b11 << 6) | /* padding */ 0b11_1111;
        218 => 0b1111_1111, 0b1111_1111, 0b1111_1010, (0b00 << 6) | /* padding */ 0b11_1111;
        219 => 0b1111_1111, 0b1111_1111, 0b1111_1010, (0b01 << 6) | /* padding */ 0b11_1111;
        238 => 0b1111_1111, 0b1111_1111, 0b1111_1010, (0b10 << 6) | /* padding */ 0b11_1111;
        240 => 0b1111_1111, 0b1111_1111, 0b1111_1010, (0b11 << 6) | /* padding */ 0b11_1111;
        242 => 0b1111_1111, 0b1111_1111, 0b1111_1011, (0b00 << 6) | /* padding */ 0b11_1111;
        243 => 0b1111_1111, 0b1111_1111, 0b1111_1011, (0b01 << 6) | /* padding */ 0b11_1111;
        255 => 0b1111_1111, 0b1111_1111, 0b1111_1011, (0b10 << 6) | /* padding */ 0b11_1111;
        203 => 0b1111_1111, 0b1111_1111, 0b1111_1011, (0b110 << 5) | /* padding */ 0b11111;
        204 => 0b1111_1111, 0b1111_1111, 0b1111_1011, (0b111 << 5) | /* padding */ 0b11111;
        211 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b000 << 5) | /* padding */ 0b11111;
        212 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b001 << 5) | /* padding */ 0b11111;
        214 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b010 << 5) | /* padding */ 0b11111;
        221 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b011 << 5) | /* padding */ 0b11111;
        222 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b100 << 5) | /* padding */ 0b11111;
        223 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b101 << 5) | /* padding */ 0b11111;
        241 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b110 << 5) | /* padding */ 0b11111;
        244 => 0b1111_1111, 0b1111_1111, 0b1111_1100, (0b111 << 5) | /* padding */ 0b11111;
        245 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b000 << 5) | /* padding */ 0b11111;
        246 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b001 << 5) | /* padding */ 0b11111;
        247 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b010 << 5) | /* padding */ 0b11111;
        248 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b011 << 5) | /* padding */ 0b11111;
        250 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b100 << 5) | /* padding */ 0b11111;
        251 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b101 << 5) | /* padding */ 0b11111;
        252 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b110 << 5) | /* padding */ 0b11111;
        253 => 0b1111_1111, 0b1111_1111, 0b1111_1101, (0b111 << 5) | /* padding */ 0b11111;
        254 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b000 << 5) | /* padding */ 0b11111;
        2 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0010 << 4) | /* padding */ 0b1111;
        3 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0011 << 4) | /* padding */ 0b1111;
        4 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0100 << 4) | /* padding */ 0b1111;
        5 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0101 << 4) | /* padding */ 0b1111;
        6 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0110 << 4) | /* padding */ 0b1111;
        7 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b0111 << 4) | /* padding */ 0b1111;
        8 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b1000 << 4) | /* padding */ 0b1111;
        11 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b1001 << 4) | /* padding */ 0b1111;
        12 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b1010 << 4) | /* padding */ 0b1111;
        14 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b1011 << 4) | /* padding */ 0b1111;
        15 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b1100 << 4) | /* padding */ 0b1111;
        16 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b1101 << 4) | /* padding */ 0b1111;
        17 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b1110 << 4) | /* padding */ 0b1111;
        18 => 0b1111_1111, 0b1111_1111, 0b1111_1110, (0b1111 << 4) | /* padding */ 0b1111;
        19 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0000 << 4) | /* padding */ 0b1111;
        20 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0001 << 4) | /* padding */ 0b1111;
        21 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0010 << 4) | /* padding */ 0b1111;
        23 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0011 << 4) | /* padding */ 0b1111;
        24 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0100 << 4) | /* padding */ 0b1111;
        25 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0101 << 4) | /* padding */ 0b1111;
        26 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0110 << 4) | /* padding */ 0b1111;
        27 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b0111 << 4) | /* padding */ 0b1111;
        28 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b1000 << 4) | /* padding */ 0b1111;
        29 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b1001 << 4) | /* padding */ 0b1111;
        30 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b1010 << 4) | /* padding */ 0b1111;
        31 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b1011 << 4) | /* padding */ 0b1111;
        127 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b1100 << 4) | /* padding */ 0b1111;
        220 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b1101 << 4) | /* padding */ 0b1111;
        249 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b1110 << 4) | /* padding */ 0b1111;
        10 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b11_1100 << 2) | /* padding */ 0b11;
        13 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b11_1101 << 2) | /* padding */ 0b11;
        22 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b11_1110 << 2) | /* padding */ 0b11;
        // 256 => 0b1111_1111, 0b1111_1111, 0b1111_1111, (0b11_1111 << 2) | /* padding */ 0b11;
        ];
    }

    /**
     * https://tools.ietf.org/html/rfc7541
     * Appendix B.  Huffman Code
     */
    #[test]
    fn test_decode_all_code_joined() {
        let bytes = vec![
            // 0     |11111111|11000
            0b1111_1111,
            (0b11000 << 3)
                // 1     |11111111|11111111|1011000
                + 0b111,
            0b1111_1111,
            0b1111_1101,
            (0b1000 << 4)
                // 2     |11111111|11111111|11111110|0010
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            0b1110_0010,
            // 3     |11111111|11111111|11111110|0011
            0b1111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b0011 << 4)
                // 4     |11111111|11111111|11111110|0100
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            0b1110_0100,
            // 5     |11111111|11111111|11111110|0101
            0b1111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b0101 << 4)
                // 6     |11111111|11111111|11111110|0110
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            0b1110_0110,
            // 7     |11111111|11111111|11111110|0111
            0b1111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b0111 << 4)
                // 8     |11111111|11111111|11111110|1000
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            0b1110_1000,
            // 9     |11111111|11111111|11101010
            0b1111_1111,
            0b1111_1111,
            0b1110_1010,
            // 10     |11111111|11111111|11111111|111100
            0b1111_1111,
            0b1111_1111,
            0b1111_1111,
            (0b11_1100 << 2)
                // 11     |11111111|11111111|11111110|1001
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            0b1111_1010,
            (0b01 << 6)
                // 12     |11111111|11111111|11111110|1010
                + 0b11_1111,
            0b1111_1111,
            0b1111_1111,
            (0b10_1010 << 2)
                // 13     |11111111|11111111|11111111|111101
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            0b1111_1111,
            (0b1101 << 4)
                // 14     |11111111|11111111|11111110|1011
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            0b1110_1011,
            // 15     |11111111|11111111|11111110|1100
            0b1111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b1100 << 4)
                // 16     |11111111|11111111|11111110|1101
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            0b1110_1101,
            // 17     |11111111|11111111|11111110|1110
            0b1111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b1110 << 4)
                // 18     |11111111|11111111|11111110|1111
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            0b1110_1111,
            // 19     |11111111|11111111|11111111|0000
            0b1111_1111,
            0b1111_1111,
            0b1111_1111,
            (0b0000 << 4)
                // 20     |11111111|11111111|11111111|0001
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            0b1111_0001,
            // 21     |11111111|11111111|11111111|0010
            0b1111_1111,
            0b1111_1111,
            0b1111_1111,
            (0b0010 << 4)
                // 22     |11111111|11111111|11111111|111110
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            0b1111_1111,
            (0b10 << 6)
                // 23     |11111111|11111111|11111111|0011
                + 0b11_1111,
            0b1111_1111,
            0b1111_1111,
            (0b11_0011 << 2)
                // 24     |11111111|11111111|11111111|0100
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            0b1111_1101,
            (0b00 << 6)
                // 25     |11111111|11111111|11111111|0101
                + 0b11_1111,
            0b1111_1111,
            0b1111_1111,
            (0b11_0101 << 2)
                // 26     |11111111|11111111|11111111|0110
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            0b1111_1101,
            (0b10 << 6)
                // 27     |11111111|11111111|11111111|0111
                + 0b11_1111,
            0b1111_1111,
            0b1111_1111,
            (0b11_0111 << 2)
                // 28     |11111111|11111111|11111111|1000
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b00 << 6)
                // 29     |11111111|11111111|11111111|1001
                + 0b11_1111,
            0b1111_1111,
            0b1111_1111,
            (0b11_1001 << 2)
                // 30     |11111111|11111111|11111111|1010
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b10 << 6)
                // 31     |11111111|11111111|11111111|1011
                + 0b11_1111,
            0b1111_1111,
            0b1111_1111,
            (0b11_1011 << 2)
                // 32     |010100
                + 0b01,
            (0b0100 << 4)
                // 33 -!- |11111110|00
                + 0b1111,
            (0b11_1000 << 2)
                // 34 -;- |11111110|01
                + 0b11,
            0b1111_1001,
            // 35 -#- |11111111|1010
            0b1111_1111,
            (0b1010 << 4)
                // 36 -$- |11111111|11001
                + 0b1111,
            0b1111_1100,
            (0b1 << 7)
                // 37 -%- |010101
                + (0b01_0101 << 1)
                // 38 -&- |11111000
                + 0b1,
            (0b111_1000 << 1)
                // 39 -'- |11111111|010
                + 0b1,
            0b1111_1110,
            (0b10 << 6)
                // 40 -(- |11111110|10
                + 0b11_1111,
            (0b1010 << 4)
                // 41 -)- |11111110|11
                + 0b1111,
            (0b11_1011 << 2)
                // 42 -*- |11111001
                + 0b11,
            (0b11_1001 << 2)
                // 43 -+- |11111111|011
                + 0b11,
            0b1111_1101,
            (0b1 << 7)
                // 44 -,- |11111010
                + 0b111_1101,
            (0b0 << 7)
                // 45 --- |010110
                + (0b01_0110 << 1)
                // 46 -.- |010111
                + 0b0,
            (0b10111 << 3)
                // 47 -/- |011000
                + 0b011,
            (0b000 << 5)
                // 48 -0- |00000
                + 0b00000,
            // 49 -1- |00001
            (0b00001 << 3)
                // 50 -2- |00010
                + 0b000,
            (0b10 << 6)
                // 51 -3- |011001
                + 0b01_1001,
            // 52 -4- |011010
            (0b01_1010 << 2)
                // 53 -5- |011011
                + 0b01,
            (0b1011 << 4)
                // 54 -6- |011100
                + 0b0111,
            (0b00 << 6)
                // 55 -7- |011101
                + 0b01_1101,
            // 56 -8- |011110
            (0b01_1110 << 2)
                // 57 -9- |011111
                + 0b01,
            (0b1111 << 4)
                // 58 -:- |1011100
                + 0b1011,
            (0b100 << 5)
                // 59     |11111011
                + 0b11111,
            (0b011 << 5)
                // 60 -<- |11111111|1111100
                + 0b11111,
            0b1111_1111,
            (0b00 << 6)
                // 61 -=- |100000
                + 0b10_0000,
            // 62 ->- |11111111|1011
            0b1111_1111,
            (0b1011 << 4)
                // 63 -?- |11111111|00
                + 0b1111,
            (0b11_1100 << 2)
                // 64 -@- |11111111|11010
                + 0b11,
            0b1111_1111,
            (0b010 << 5)
                // 65 -A- |100001
                + 0b10000,
            (0b1 << 7)
                // 66 -B- |1011101
                + 0b101_1101,
            // 67 -C- |1011110
            (0b101_1110 << 1)
                // 68 -D- |1011111
                + 0b1,
            (0b01_1111 << 2)
                // 69 -E- |1100000
                + 0b11,
            (0b00000 << 3)
                // 70 -F- |1100001
                + 0b110,
            (0b0001 << 4)
                // 71 -G- |1100010
                + 0b1100,
            (0b010 << 5)
                // 72 -H- |1100011
                + 0b11000,
            (0b11 << 6)
                // 73 -I- |1100100
                + 0b11_0010,
            (0b0 << 7)
                // 74 -J- |1100101
                + 0b110_0101,
            // 75 -K- |1100110
            (0b110_0110 << 1)
                // 76 -L- |1100111
                + 0b1,
            (0b10_0111 << 2)
                // 77 -M- |1101000
                + 0b11,
            (0b01000 << 3)
                // 78 -N- |1101001
                + 0b110,
            (0b1001 << 4)
                // 79 -O- |1101010
                + 0b1101,
            (0b010 << 5)
                // 80 -P- |1101011
                + 0b11010,
            (0b11 << 6)
                // 81 -Q- |1101100
                + 0b11_0110,
            (0b0 << 7)
                // 82 -R- |1101101
                + 0b110_1101,
            // 83 -S- |1101110
            (0b110_1110 << 1)
                // 84 -T- |1101111
                + 0b1,
            (0b10_1111 << 2)
                // 85 -U- |1110000
                + 0b11,
            (0b10000 << 3)
                // 86 -V- |1110001
                + 0b111,
            (0b0001 << 4)
                // 87 -W- |1110010
                + 0b1110,
            (0b010 << 5)
                // 88 -X- |11111100
                + 0b11111,
            (0b100 << 5)
                // 89 -Y- |1110011
                + 0b11100,
            (0b11 << 6)
                // 90 -Z- |11111101
                + 0b11_1111,
            (0b01 << 6)
                // 91 -[- |11111111|11011
                + 0b11_1111,
            (0b111_1011 << 1)
                // 92 -\- |11111111|11111110|000
                + 0b1,
            0b1111_1111,
            0b1111_1100,
            (0b00 << 6)
                // 93 -]- |11111111|11100
                + 0b11_1111,
            (0b111_1100 << 1)
                // 94 -^- |11111111|111100
                + 0b1,
            0b1111_1111,
            (0b11100 << 3)
                // 95 -_- |100010
                + 0b100,
            (0b010 << 5)
                // 96 -`- |11111111|1111101
                + 0b11111,
            0b1111_1111,
            (0b01 << 6)
                // 97 -a- |00011
                + (0b00011 << 1)
                // 98 -b- |100011
                + 0b1,
            (0b00011 << 3)
                // 99 -c- |00100
                + 0b001,
            (0b00 << 6)
                // 100 -d- |100100
                + 0b10_0100,
            // 101 -e- |00101
            (0b00101 << 3)
                // 102 -f- |100101
                + 0b100,
            (0b101 << 5)
                // 103 -g- |100110
                + 0b10011,
            (0b0 << 7)
                // 104 -h- |100111
                + (0b10_0111 << 1)
                // 105 -i- |00110
                + 0b0,
            (0b0110 << 4)
                // 106 -j- |1110100
                + 0b1110,
            (0b100 << 5)
                // 107 -k- |1110101
                + 0b11101,
            (0b01 << 6)
                // 108 -l- |101000
                + 0b10_1000,
            // 109 -m- |101001
            (0b10_1001 << 2)
                // 110 -n- |101010
                + 0b10,
            (0b1010 << 4)
                // 111 -o- |00111
                + 0b0011,
            (0b1 << 7)
                // 112 -p- |101011
                + (0b10_1011 << 1)
                // 113 -q- |1110110
                + 0b1,
            (0b11_0110 << 2)
                // 114 -r- |101100
                + 0b10,
            (0b1100 << 4)
                // 115 -s- |01000
                + 0b0100,
            (0b0 << 7)
                // 116 -t- |01001
                + (0b01001 << 2)
                // 117 -u- |101101
                + 0b10,
            (0b1101 << 4)
                // 118 -v- |1110111
                + 0b1110,
            (0b111 << 5)
                // 119 -w- |1111000
                + 0b11110,
            (0b00 << 6)
                // 120 -x- |1111001
                + 0b11_1100,
            (0b1 << 7)
                // 121 -y- |1111010
                + 0b111_1010,
            // 122 -z- |1111011
            (0b111_1011 << 1)
                // 123 -{- |11111111|1111110
                + 0b1,
            0b1111_1111,
            (0b11_1110 << 2)
                // 124 -|- |11111111|100
                + 0b11,
            0b1111_1110,
            (0b0 << 7)
                // 125 -}- |11111111|111101
                + 0b111_1111,
            (0b111_1101 << 1)
                // 126 -~- |11111111|11101
                + 0b1,
            0b1111_1111,
            (0b1101 << 4)
                // 127     |11111111|11111111|11111111|1100
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            0b1111_1100,
            // 128     |11111111|11111110|0110
            0b1111_1111,
            0b1111_1110,
            (0b0110 << 4)
                // 129     |11111111|11111111|010010
                + 0b1111,
            0b1111_1111,
            0b1111_0100,
            (0b10 << 6)
                // 130     |11111111|11111110|0111
                + 0b11_1111,
            0b1111_1111,
            (0b10_0111 << 2)
                // 131     |11111111|11111110|1000
                + 0b11,
            0b1111_1111,
            0b1111_1010,
            (0b00 << 6)
                // 132     |11111111|11111111|010011
                + 0b11_1111,
            0b1111_1111,
            0b1101_0011,
            // 133     |11111111|11111111|010100
            0b1111_1111,
            0b1111_1111,
            (0b01_0100 << 2)
                // 134     |11111111|11111111|010101
                + 0b11,
            0b1111_1111,
            0b1111_1101,
            (0b0101 << 4)
                // 135     |11111111|11111111|1011001
                + 0b1111,
            0b1111_1111,
            0b1111_1011,
            (0b001 << 5)
                // 136     |11111111|11111111|010110
                + 0b11111,
            0b1111_1111,
            0b1110_1011,
            (0b0 << 7)
                // 137     |11111111|11111111|1011010
                + 0b111_1111,
            0b1111_1111,
            0b1101_1010,
            // 138     |11111111|11111111|1011011
            0b1111_1111,
            0b1111_1111,
            (0b101_1011 << 1)
                // 139     |11111111|11111111|1011100
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            (0b01_1100 << 2)
                // 140     |11111111|11111111|1011101
                + 0b11,
            0b1111_1111,
            0b1111_1110,
            (0b11101 << 3)
                // 141     |11111111|11111111|1011110
                + 0b111,
            0b1111_1111,
            0b1111_1101,
            (0b1110 << 4)
                // 142     |11111111|11111111|11101011
                + 0b1111,
            0b1111_1111,
            0b1111_1110,
            (0b1011 << 4)
                // 143     |11111111|11111111|1011111
                + 0b1111,
            0b1111_1111,
            0b1111_1011,
            (0b111 << 5)
                // 144     |11111111|11111111|11101100
                + 0b11111,
            0b1111_1111,
            0b1111_1101,
            (0b100 << 5)
                // 145     |11111111|11111111|11101101
                + 0b11111,
            0b1111_1111,
            0b1111_1101,
            (0b101 << 5)
                // 146     |11111111|11111111|010111
                + 0b11111,
            0b1111_1111,
            0b1110_1011,
            (0b1 << 7)
                // 147     |11111111|11111111|1100000
                + 0b111_1111,
            0b1111_1111,
            0b1110_0000,
            // 148     |11111111|11111111|11101110
            0b1111_1111,
            0b1111_1111,
            0b1110_1110,
            // 149     |11111111|11111111|1100001
            0b1111_1111,
            0b1111_1111,
            (0b110_0001 << 1)
                // 150     |11111111|11111111|1100010
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            (0b10_0010 << 2)
                // 151     |11111111|11111111|1100011
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            (0b00011 << 3)
                // 152     |11111111|11111111|1100100
                + 0b111,
            0b1111_1111,
            0b1111_1110,
            (0b0100 << 4)
                // 153     |11111111|11111110|11100
                + 0b1111,
            0b1111_1111,
            0b1110_1110,
            (0b0 << 7)
                // 154     |11111111|11111111|011000
                + 0b111_1111,
            0b1111_1111,
            (0b101_1000 << 1)
                // 155     |11111111|11111111|1100101
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            (0b10_0101 << 2)
                // 156     |11111111|11111111|011001
                + 0b11,
            0b1111_1111,
            0b1111_1101,
            (0b1001 << 4)
                // 157     |11111111|11111111|1100110
                + 0b1111,
            0b1111_1111,
            0b1111_1100,
            (0b110 << 5)
                // 158     |11111111|11111111|1100111
                + 0b11111,
            0b1111_1111,
            0b1111_1001,
            (0b11 << 6)
                // 159     |11111111|11111111|11101111
                + 0b11_1111,
            0b1111_1111,
            0b1111_1011,
            (0b11 << 6)
                // 160     |11111111|11111111|011010
                + 0b11_1111,
            0b1111_1111,
            0b1101_1010,
            // 161     |11111111|11111110|11101
            0b1111_1111,
            0b1111_1110,
            (0b11101 << 3)
                // 162     |11111111|11111110|1001
                + 0b111,
            0b1111_1111,
            0b1111_0100,
            (0b1 << 7)
                // 163     |11111111|11111111|011011
                + 0b111_1111,
            0b1111_1111,
            (0b101_1011 << 1)
                // 164     |11111111|11111111|011100
                + 0b1,
            0b1111_1111,
            0b1111_1110,
            (0b11100 << 3)
                // 165     |11111111|11111111|1101000
                + 0b111,
            0b1111_1111,
            0b1111_1110,
            (0b1000 << 4)
                // 166     |11111111|11111111|1101001
                + 0b1111,
            0b1111_1111,
            0b1111_1101,
            (0b001 << 5)
                // 167     |11111111|11111110|11110
                + 0b11111,
            0b1111_1111,
            0b1101_1110,
            // 168     |11111111|11111111|1101010
            0b1111_1111,
            0b1111_1111,
            (0b110_1010 << 1)
                // 169     |11111111|11111111|011101
                + 0b1,
            0b1111_1111,
            0b1111_1110,
            (0b11101 << 3)
                // 170     |11111111|11111111|011110
                + 0b111,
            0b1111_1111,
            0b1111_1011,
            (0b110 << 5)
                // 171     |11111111|11111111|11110000
                + 0b11111,
            0b1111_1111,
            0b1111_1110,
            (0b000 << 5)
                // 172     |11111111|11111110|11111
                + 0b11111,
            0b1111_1111,
            0b1101_1111,
            // 173     |11111111|11111111|011111
            0b1111_1111,
            0b1111_1111,
            (0b01_1111 << 2)
                // 174     |11111111|11111111|1101011
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            (0b01011 << 3)
                // 175     |11111111|11111111|1101100
                + 0b111,
            0b1111_1111,
            0b1111_1110,
            (0b1100 << 4)
                // 176     |11111111|11111111|00000
                + 0b1111,
            0b1111_1111,
            0b1111_0000,
            (0b0 << 7)
                // 177     |11111111|11111111|00001
                + 0b111_1111,
            0b1111_1111,
            (0b10_0001 << 2)
                // 178     |11111111|11111111|100000
                + 0b11,
            0b1111_1111,
            0b1111_1110,
            (0b0000 << 4)
                // 179     |11111111|11111111|00010
                + 0b1111,
            0b1111_1111,
            0b1111_0001,
            (0b0 << 7)
                // 180     |11111111|11111111|1101101
                + 0b111_1111,
            0b1111_1111,
            0b1110_1101,
            // 181     |11111111|11111111|100001
            0b1111_1111,
            0b1111_1111,
            (0b10_0001 << 2)
                // 182     |11111111|11111111|1101110
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            (0b01110 << 3)
                // 183     |11111111|11111111|1101111
                + 0b111,
            0b1111_1111,
            0b1111_1110,
            (0b1111 << 4)
                // 184     |11111111|11111110|1010
                + 0b1111,
            0b1111_1111,
            0b1110_1010,
            // 185     |11111111|11111111|100010
            0b1111_1111,
            0b1111_1111,
            (0b10_0010 << 2)
                // 186     |11111111|11111111|100011
                + 0b11,
            0b1111_1111,
            0b1111_1110,
            (0b0011 << 4)
                // 187     |11111111|11111111|100100
                + 0b1111,
            0b1111_1111,
            0b1111_1001,
            (0b00 << 6)
                // 188     |11111111|11111111|1110000
                + 0b11_1111,
            0b1111_1111,
            0b1111_1000,
            (0b0 << 7)
                // 189     |11111111|11111111|100101
                + 0b111_1111,
            0b1111_1111,
            (0b110_0101 << 1)
                // 190     |11111111|11111111|100110
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            (0b00110 << 3)
                // 191     |11111111|11111111|1110001
                + 0b111,
            0b1111_1111,
            0b1111_1111,
            (0b0001 << 4)
                // 192     |11111111|11111111|11111000|00
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b10_0000 << 2)
                // 193     |11111111|11111111|11111000|01
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            0b1110_0001,
            // 194     |11111111|11111110|1011
            0b1111_1111,
            0b1111_1110,
            (0b1011 << 4)
                // 195     |11111111|11111110|001
                + 0b1111,
            0b1111_1111,
            (0b111_0001 << 1)
                // 196     |11111111|11111111|100111
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            (0b00111 << 3)
                // 197     |11111111|11111111|1110010
                + 0b111,
            0b1111_1111,
            0b1111_1111,
            (0b0010 << 4)
                // 198     |11111111|11111111|101000
                + 0b1111,
            0b1111_1111,
            0b1111_1010,
            (0b00 << 6)
                // 199     |11111111|11111111|11110110|0
                + 0b11_1111,
            0b1111_1111,
            0b1111_1101,
            (0b100 << 5)
                // 200     |11111111|11111111|11111000|10
                + 0b11111,
            0b1111_1111,
            0b1111_1111,
            (0b00010 << 3)
                // 201     |11111111|11111111|11111000|11
                + 0b111,
            0b1111_1111,
            0b1111_1111,
            (0b110_0011 << 1)
                // 202     |11111111|11111111|11111001|00
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            0b1111_0010,
            (0b0 << 7)
                // 203     |11111111|11111111|11111011|110
                + 0b111_1111,
            0b1111_1111,
            0b1111_1101,
            (0b1110 << 4)
                // 204     |11111111|11111111|11111011|111
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b101_1111 << 1)
                // 205     |11111111|11111111|11111001|01
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            0b1111_0010,
            (0b1 << 7)
                // 206     |11111111|11111111|11110001
                + 0b111_1111,
            0b1111_1111,
            0b1111_1000,
            (0b1 << 7)
                // 207     |11111111|11111111|11110110|1
                + 0b111_1111,
            0b1111_1111,
            0b1111_1011,
            (0b01 << 6)
                // 208     |11111111|11111110|010
                + 0b11_1111,
            0b1111_1111,
            (0b10010 << 3)
                // 209     |11111111|11111111|00011
                + 0b111,
            0b1111_1111,
            0b1111_1000,
            (0b11 << 6)
                // 210     |11111111|11111111|11111001|10
                + 0b11_1111,
            0b1111_1111,
            0b1111_1110,
            (0b0110 << 4)
                // 211     |11111111|11111111|11111100|000
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b110_0000 << 1)
                // 212     |11111111|11111111|11111100|001
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            0b1111_1000,
            (0b01 << 6)
                // 213     |11111111|11111111|11111001|11
                + 0b11_1111,
            0b1111_1111,
            0b1111_1110,
            (0b0111 << 4)
                // 214     |11111111|11111111|11111100|010
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b110_0010 << 1)
                // 215     |11111111|11111111|11110010
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            (0b111_0010 << 1)
                // 216     |11111111|11111111|00100
                + 0b1,
            0b1111_1111,
            0b1111_1110,
            (0b0100 << 4)
                // 217     |11111111|11111111|00101
                + 0b1111,
            0b1111_1111,
            0b1111_0010,
            (0b1 << 7)
                // 218     |11111111|11111111|11111010|00
                + 0b111_1111,
            0b1111_1111,
            0b1111_1101,
            (0b000 << 5)
                // 219     |11111111|11111111|11111010|01
                + 0b11111,
            0b1111_1111,
            0b1111_1111,
            (0b01001 << 3)
                // 220     |11111111|11111111|11111111|1101
                + 0b111,
            0b1111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b1 << 7)
                // 221     |11111111|11111111|11111100|011
                + 0b111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b0011 << 4)
                // 222     |11111111|11111111|11111100|100
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b110_0100 << 1)
                // 223     |11111111|11111111|11111100|101
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            0b1111_1001,
            (0b01 << 6)
                // 224     |11111111|11111110|1100
                + 0b11_1111,
            0b1111_1111,
            (0b10_1100 << 2)
                // 225     |11111111|11111111|11110011
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            (0b11_0011 << 2)
                // 226     |11111111|11111110|1101
                + 0b11,
            0b1111_1111,
            0b1111_1011,
            (0b01 << 6)
                // 227     |11111111|11111111|00110
                + 0b11_1111,
            0b1111_1111,
            (0b110_0110 << 1)
                // 228     |11111111|11111111|101001
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            (0b01001 << 3)
                // 229     |11111111|11111111|00111
                + 0b111,
            0b1111_1111,
            0b1111_1001,
            (0b11 << 6)
                // 230     |11111111|11111111|01000
                + 0b11_1111,
            0b1111_1111,
            (0b110_1000 << 1)
                // 231     |11111111|11111111|1110011
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            (0b11_0011 << 2)
                // 232     |11111111|11111111|101010
                + 0b11,
            0b1111_1111,
            0b1111_1110,
            (0b1010 << 4)
                // 233     |11111111|11111111|101011
                + 0b1111,
            0b1111_1111,
            0b1111_1010,
            (0b11 << 6)
                // 234     |11111111|11111111|11110111|0
                + 0b11_1111,
            0b1111_1111,
            0b1111_1101,
            (0b110 << 5)
                // 235     |11111111|11111111|11110111|1
                + 0b11111,
            0b1111_1111,
            0b1111_1110,
            (0b1111 << 4)
                // 236     |11111111|11111111|11110100
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b0100 << 4)
                // 237     |11111111|11111111|11110101
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b0101 << 4)
                // 238     |11111111|11111111|11111010|10
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b10_1010 << 2)
                // 239     |11111111|11111111|1110100
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            (0b10100 << 3)
                // 240     |11111111|11111111|11111010|11
                + 0b111,
            0b1111_1111,
            0b1111_1111,
            (0b110_1011 << 1)
                // 241     |11111111|11111111|11111100|110
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            0b1111_1001,
            (0b10 << 6)
                // 242     |11111111|11111111|11111011|00
                + 0b11_1111,
            0b1111_1111,
            0b1111_1110,
            (0b1100 << 4)
                // 243     |11111111|11111111|11111011|01
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b10_1101 << 2)
                // 244     |11111111|11111111|11111100|111
                + 0b11,
            0b1111_1111,
            0b1111_1111,
            0b1111_0011,
            (0b1 << 7)
                // 245     |11111111|11111111|11111101|000
                + 0b111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b1000 << 4)
                // 246     |11111111|11111111|11111101|001
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b110_1001 << 1)
                // 247     |11111111|11111111|11111101|010
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            0b1111_1010,
            (0b10 << 6)
                // 248     |11111111|11111111|11111101|011
                + 0b11_1111,
            0b1111_1111,
            0b1111_1111,
            (0b01011 << 3)
                // 249     |11111111|11111111|11111111|1110
                + 0b111,
            0b1111_1111,
            0b1111_1111,
            0b1111_1111,
            (0b0 << 7)
                // 250     |11111111|11111111|11111101|100
                + 0b111_1111,
            0b1111_1111,
            0b1111_1110,
            (0b1100 << 4)
                // 251     |11111111|11111111|11111101|101
                + 0b1111,
            0b1111_1111,
            0b1111_1111,
            (0b110_1101 << 1)
                // 252     |11111111|11111111|11111101|110
                + 0b1,
            0b1111_1111,
            0b1111_1111,
            0b1111_1011,
            (0b10 << 6)
                // 253     |11111111|11111111|11111101|111
                + 0b11_1111,
            0b1111_1111,
            0b1111_1111,
            (0b01111 << 3)
                // 254     |11111111|11111111|11111110|000
                + 0b111,
            0b1111_1111,
            0b1111_1111,
            0b1111_0000,
            // 255     |11111111|11111111|11111011|10
            0b1111_1111,
            0b1111_1111,
            0b1111_1011,
            (0b10 << 6)
                // 256 eof |11111111|11111111|11111111|111111
                + 0b11_1111,
            0b1111_1111,
            0b1111_1111,
            0b1111_1111,
        ];
        let expected = (0u8..=255).collect();
        let res: Result<Vec<_>, Error> = bytes.hpack_decode().collect();
        assert_eq!(res, Ok(expected));
    }
}
